﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections.Specialized;
using System.Collections.ObjectModel;

namespace Triples {
    public class Board : IEnumerable <IPlayableCard>, INotifyCollectionChanged {

        private readonly ObservableCollection<IPlayableCard> Cards;
        private readonly List<IPlayableCard> BoardPositions;

        public event NotifyCollectionChangedEventHandler CollectionChanged {
            add { Cards.CollectionChanged += value; }
            remove { Cards.CollectionChanged -= value; }
        }

        public IPlayableCard this[int i] {
            get { return BoardPositions.ElementAtOrDefault (i); }
        }

		
		public int Size {
            get { return Cards.Count; }
		}
		

        public Board() {
            Cards = new ObservableCollection<IPlayableCard>();
            BoardPositions = new List<IPlayableCard>();
        }


        public override string ToString() {
            return base.ToString();
        }


        public IEnumerator<IPlayableCard> GetEnumerator() {
            return Cards.GetEnumerator();
        }


        System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() {
            return Cards.GetEnumerator();
        }


        internal void PickUpCard(IPlayableCard card) {

            if (null != card && card.Position.HasValue) {
                int idx = card.Position.Value;

                if (0 <= idx && BoardPositions.Count > idx) {
                    bool isEmptiedSlot = null != BoardPositions[idx];

                    if (isEmptiedSlot) {
                        BoardPositions[idx] = null;
                        card.Position = null;
                        Cards.Remove(card);
                    }
                }

                else throw new ArgumentException();
            }
        }

        
        internal void PlaceCard(IPlayableCard card) {

            if (null != card) {
                bool isPlaced = false;
                int position = -1;

                for (int i = 0; i < BoardPositions.Count; i++) {
                    if (null != BoardPositions[i]) continue;
                    //BoardPositions[i] = card;
                    position = i; 
                    isPlaced = true;
                    break;
                }

                if (!isPlaced) {
                    BoardPositions.Add(null);
                    position = BoardPositions.Count - 1;
                    isPlaced = true;
                }

                if (card.Position.HasValue) BoardPositions[card.Position.Value] = null;
                else Cards.Add(card);

                BoardPositions[position] = card;
                card.Position = position;
            }
        }


        internal void CompactBoard() {
            int i;

            for (i = BoardPositions.Count - 1; 0 <= i; i--) {
                if (null != BoardPositions[i]) break;
            }

            if (i >= 0) {
                PlaceCard(BoardPositions[i]);
            }
        }
    }
}
